package bg.unisofia.fmi.tis.ui.bean;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class BackingBeanBase implements Serializable {

    private static Map<String, Object> fakeContextMap;
	
    protected static FacesContext getContext() {
        return FacesContext.getCurrentInstance();
    }
    
    protected static String getContextRoot() {
        return ((HttpServletRequest) getContext().getExternalContext().getRequest()).getContextPath();
    }

    public String getContextPath() {
    	return getRequest().getContextPath();
    }
    
    protected HttpServletRequest getRequest() {
        FacesContext context = getContext();
        return (HttpServletRequest) context.getExternalContext().getRequest();
    }

    protected HttpServletResponse getResponse() {
        return (HttpServletResponse) getContext().getExternalContext().getResponse();
    }
    
    protected HttpSession getSession() {
        FacesContext context = getContext();
        return (HttpSession) context.getExternalContext().getSession(true);
    }
    
    protected String getContextParameter(String name) {
        return getSession().getServletContext().getInitParameter(name);
    }
    
    /** Uses JSF mechanisms for finding a bean in the proper scope - if it exists - or creating
     * an instance and putting it into the proper scope. All the configuration in the jsf config files will be taken into account.
     *@param aClass The class of the bean
     *@param name The name under which the bean was declared in the config file
     */
    protected static <E> E getManagedBean(Class<E> aClass, String name) {
        if (getContext() == null) {
            if (fakeContextMap == null) {
                fakeContextMap = new HashMap<String, Object>();
            }

            Object o = fakeContextMap.get(name);
            if (o == null) {
                try {
                    o = aClass.newInstance();
                    fakeContextMap.put(name, o);
                } catch (Exception e) {
                    e.printStackTrace();
                    return null;
                }
            }
            
            return aClass.cast(o);
        }

        return (E) getContext().getApplication().getVariableResolver().resolveVariable(getContext(), name);
    }
    
    /**
     *The name is constructed like that: "mb"+simple class name. So for UserBean, mbSiteBean name would be used.
     */
    public static <E> E getManagedBean(Class<E> aClass) {
        return getManagedBean(aClass, "mb" + aClass.getSimpleName());
    }
    
    protected void addMessage(FacesMessage.Severity severity, String clientId, String msgText) {
        FacesMessage msg = new FacesMessage(severity, msgText, msgText);
        getContext().addMessage(clientId, msg);
    }
    
    public String getFormName(){
        return "";
    }
}
